import {
    getKeyFrameOptionByCamera
} from './BQGIS-navigationPath'

export function BQGIS_navigationFlyLoop(viewer = window.viewer, endCallBack = () => {}) {
    this.viewer = viewer
    this.state = 'stop'
    this.pauseKeyFrame = null
    this.pauseIndex = 0
    this.navigationPath = {}
    this.endCallBack = endCallBack
}

BQGIS_navigationFlyLoop.prototype.playNavigationPath = function (navigationPath, isKeyframe) {
    this.navigationPath = navigationPath
    if (!navigationPath.positions || !navigationPath.positions.length || this.state === 'play') return
    const startPoint = navigationPath.positions[0]
    this.state = 'play'
    this.pauseKeyFrame = null
    this.pauseIndex = 0
    this.viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(startPoint.lng, startPoint.lat, startPoint.alt), // 设置位置
        orientation: { // 设置角度
            heading: Cesium.Math.toRadians(startPoint.heading),
            pitch: Cesium.Math.toRadians(startPoint.pitch),
            roll: Cesium.Math.toRadians(startPoint.roll)
        }
    })
    const positions = navigationPath.positions.map(({
        lng,
        lat,
        alt,
        heading,
        pitch,
        roll,
        speed = null
    }, index) => {
        const option = {
            lng,
            lat,
            alt,
            heading,
            pitch,
            roll,
            stop: 0,
            onStart: () => {
                this.pauseIndex = index
            }
        }
        if (index > 0) {
            if (isKeyframe && speed !== null) { // 使用 关键帧时间 并且 关键帧时间存在
                option.duration = speed
            } else { // 使用路径速度，计算出运动时间
                const duration = disTance(option, navigationPath.positions[index - 1]) / navigationPath.speed
                option.duration = duration
            }
        }
        return option
    })
    this.viewer.setCameraViewList(positions, {
        complete: () => {
            this.state = 'stop'
            this.endCallBack()
        }
    })
}

BQGIS_navigationFlyLoop.prototype.pauseNavigationPath = function () {
    if (this.state === 'play') {
        this.viewer.camera.cancelFlight()
        this.state = 'pause'
        this.pauseKeyFrame = getKeyFrameOptionByCamera(this.viewer)
    }
}

BQGIS_navigationFlyLoop.prototype.stopNavigationPath = function () {
    this.viewer.camera.cancelFlight();
    this.state = 'stop'
    this.pauseKeyFrame = null
    this.pauseIndex = 0
}

BQGIS_navigationFlyLoop.prototype.proceedNavigationPath = function () {
    if (this.state === 'pause' && this.navigationPath.positions && this.pauseIndex < this.navigationPath.positions.length) {
        this.state = 'play'
        this.viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(...this.pauseKeyFrame.cameraPose.position), // 设置位置
            orientation: { // 设置角度
                heading: Cesium.Math.toRadians(this.pauseKeyFrame.cameraPose.heading),
                pitch: Cesium.Math.toRadians(this.pauseKeyFrame.cameraPose.pitch),
                roll: Cesium.Math.toRadians(this.pauseKeyFrame.cameraPose.roll)
            }
        })
        const pauseIndex = this.pauseIndex
        const surplusNavigationPath = this.navigationPath.positions.slice(pauseIndex)

        surplusNavigationPath.unshift({
            lng: this.pauseKeyFrame.cameraPose.position[0],
            lat: this.pauseKeyFrame.cameraPose.position[1],
            alt: this.pauseKeyFrame.cameraPose.position[2],
            heading: this.pauseKeyFrame.cameraPose.heading,
            pitch: this.pauseKeyFrame.cameraPose.pitch,
            roll: this.pauseKeyFrame.cameraPose.roll
        })
        const positions = surplusNavigationPath.map(({
            lng,
            lat,
            alt,
            heading,
            pitch,
            roll,
        }, index) => {
            const option = {
                lng,
                lat,
                alt,
                heading,
                pitch,
                roll,
                stop: 0,
                onStart: () => {
                    this.pauseIndex = index
                }
            }
            if (index > 0) {
                const duration = disTance(option, surplusNavigationPath[index - 1]) / this.navigationPath.speed
                option.duration = duration
            }
            return option
        })
        this.viewer.setCameraViewList(positions, {
            maximumHeight: 0,
            complete: () => {
                this.state = 'stop'
                this.endCallBack()
            }
        })
    }
}

function disTance(point1, point2) {
    const start = Cesium.Cartographic.fromDegrees(point1.lng, point1.lat, point1.alt)
    const end = Cesium.Cartographic.fromDegrees(point2.lng, point2.lat, point2.alt)
    const geodesic = new Cesium.EllipsoidGeodesic();
    const altIntercept = point1.alt - point2.alt
    geodesic.setEndPoints(start, end);
    const result = Math.sqrt(Math.pow(geodesic.surfaceDistance, 2) + Math.pow(altIntercept, 2))
    return result
}